import { Body, Controller, Get, Inject, InternalServerErrorException, Post, Query, Req, Res } from '@nestjs/common';
import { WeixinService } from '../service/weixin.service';
import { JsonApiResponse } from '@utils/json.api.response';
// import * as fs from 'fs'
// import path from 'path';
import dayjs from 'dayjs';
import { Response, response } from 'express';
import * as Axios from 'axios'
import { CACHE_MANAGER } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { EntityManager, Knex, MikroORM, knex } from '@mikro-orm/mysql';
import { InjectEntityManager, InjectMikroORM } from '@mikro-orm/nestjs';
import { knext } from 'knext';
import { OfficePosts } from '@databases/entities/OfficePosts';
import { OfficeNews } from '@databases/entities/OfficeNews';
import { OfficeAccounts } from '@databases/entities/OfficeAccounts';
import { join } from 'path';
import { OfficeNewsSendRecords } from '@databases/entities/OfficeNewsSendRecords';
import _ from 'lodash';
import { request } from 'http';
import { OfficeNewsPostsPivots } from '@databases/entities/OfficeNewsPostsPivots';
import * as Utils from 'node-easywechat/dist/Core/Utils'
import MiniProgram from 'node-easywechat/dist/MiniProgram/Application';

@Controller('wx')
export class WxController {
    constructor(
        @InjectMikroORM('zp')
        private readonly orm: MikroORM,
        @InjectEntityManager('zp')
        private readonly em: EntityManager,
        @Inject(WeixinService) 
        private readonly weixinService : WeixinService,
        @Inject(CACHE_MANAGER) 
        private cache: Cache
    ){
        
    }

    @Get('web')
    async query(@Res() response : Response){

        let content : string = await this.cache.get('https://mp.weixin.qq.com/s/7rDw1EMQQMbcF8orePKXhw')

        if(!content)
        {
            const res = await Axios.default.get('https://mp.weixin.qq.com/s/7rDw1EMQQMbcF8orePKXhw') 
    
            const headers : any = res.headers
            
            for (const key in res.headers) {
                response.header(key,headers[key])
            }
    
            response.header('X-Frame-Options','ALLOWALL')
            response.header('Content-Security-Policy','http://localhost:5173')
    
            content  = res.data
            content = content.replaceAll('https://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')
            content = content.replaceAll('http://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')
            content = content.replaceAll('https://mmbiz.qlogo.cn','http://www.apesk.net/mmbiz')
            
            //content = content.replaceAll('<html class="\n/">',`
            content = content.replace(/<html (.*?)>/gms,
                `<html $1 >
                        <style>
                            ::-webkit-scrollbar {
                                display: none;
                                width: 0 !important;
                                height: 0 !important;
                                -webkit-appearance: none;
                                background: transparent;
                            }
                        </style> 
                `) 
        }

        await this.cache.set('https://mp.weixin.qq.com/s/7rDw1EMQQMbcF8orePKXhw',content,20000)
     
        response.send(content)
        //return res
    }

    // @Get('web')
    // async query(@Res() response : Response){


    //         const res = await Axios.default.get('https://mp.weixin.qq.com/s/7rDw1EMQQMbcF8orePKXhw') 
    
    //         const headers : any = res.headers
            
    //         for (const key in res.headers) {
    //             response.header(key,headers[key])
    //         }
    
    //         response.header('X-Frame-Options','ALLOWALL')
    //         response.header('Content-Security-Policy','http://localhost:5173')
     
    //     response.send(res.data)
    //     //return res
    // }

    @Get('wx_open_auth')
    async wxOpenAuthor(){

       const url = this.weixinService.officialAccount.oauth
        .withRedirectUrl('http://www.apesk.net')
        .withScopes('snsapi_base')
        .withState('123')
        .redirect()
    
        //`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${config.app_id}&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect`

        //{"status":0,"message":"成功","data":"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd96f2c1982b61eb2&redirect_uri=http%3A%2F%2Fwww.apesk.net&scope=snsapi_base&response_type=code&connect_redirect=1&state=123#wechat_redirect"}
        return JsonApiResponse.string(url)
    }

    @Get('wx_url_schema')
    async wxUrlSchema()
    {
        try {
            const config = await this.weixinService
            .wxMiniApp.url_scheme.generate({
                jump_wxa:{
                    path:'/pages/index/index',
                    query: "id=123",
                    env_version: "release",
                },
                is_expire:true,
                expire_type:1,
                expire_interval:1,
            })

            return JsonApiResponse.object(config)
        }catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    @Get('wx_url_link')
    async wxUrlLink()
    {
        try {
            const config = await this.weixinService
            .wxMiniApp.url_link.generate({
                path:'/pages/index/index',
                query: "id=123",
                env_version: "release",
                is_expire:true,
                expire_type:1,
                expire_interval:1,
            })

            return JsonApiResponse.object(config)
        }catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }


    @Get('wxshare')
    async wxShare(@Res() response)
    {
        try {
            const config = await this.weixinService
            .officialAccount.jssdk.getConfigArray(
                [
                    'checkJsApi',
                    'updateAppMessageShareData',
                    'updateTimelineShareData'
                ],
                true,//Debug
                true,//beta
                ['wx-open-launch-weapp'], //openTagList
                'http://www.apesk.net/api/common/wx/jsdk_config'
            )

            return JsonApiResponse.object(config)

            //const htmlContent = response.render('template',config)

            const htmlContent = response.render('share',{
                config:config
                // {
                //     "appId":"wxd96f2c1982b61eb2",
                //     "nonceStr":"BRbpSmyMjaS36ZzDRAW6CQJrhMQDRrYj",
                //     "timestamp":"1699545974",
                //     "url":"http://www.apesk.net/api/common/wx/jsdk_config",
                //     "signature":"3b13a250e8038f22eb5629ee30294c2fcaa994e5"
                // }
            })
 
            // return JsonApiResponse.string(htmlContent)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    @Get('jsdk_config')
    async jsdkConfig(@Query('url') url)
    {
        try {
            const config = await this.weixinService
            .officialAccount.jssdk.getConfigArray(
                [
                    'checkJsApi',
                    'updateAppMessageShareData',
                    'updateTimelineShareData'
                ],
                false,//Debug
                false,//beta
                ['wx-open-launch-weapp'], //openTagList
                url
            )

            return JsonApiResponse.object(config)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    @Get('sign_info')
    async sign_info(req : Request,@Query() querys){
        return await this.weixinService.callback(querys)
    }

    @Get('upload_temp_media')
    async uploadTempMedia()
    {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpUpload('https://api.weixin.qq.com/cgi-bin/media/upload?type=image',[
                '/www/wwwroot/nest.apesk.net/static/post-head.png'
            ])

            //{"type":"image","media_id":"mUlBLkIm48uQ_uA1yfv521_cwd7IWKOlGFjavfbdnUKZ4KBzbY1Ok-rMsAKG0JLk","created_at":1698262200,"item":[]}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
        
    }

    //永久素材上传
    @Get('upload_img')
    async uploadImage(){
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpUpload('https://api.weixin.qq.com/cgi-bin/media/uploadimg',[
                '/www/wwwroot/nest.apesk.net/static/post-head.png'
            ],{
                // 'filename':'back-image.png',
                // 'content-type':'image/png' 
            })

            //http://mmbiz.qpic.cn/sz_mmbiz_png/xcFRQm9TQh0UK8G46r58IM5SOZp8rWvTMDImfpmX2lefwhOLCicNobpEcExQHHVBWd0kQwahJOCjvBjdzmaJYicw/0
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //新建一个图文消息到临时素材
    @Get('upload_news')
    async uploadNews() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/media/uploadnews',{
                "articles": [	 
                    {
                        "thumb_media_id":"mUlBLkIm48uQ_uA1yfv521_cwd7IWKOlGFjavfbdnUKZ4KBzbY1Ok-rMsAKG0JLk",
                        "author":"武则天",		
                        "title":"每日日结兼职,等你来!",		 	
                        "content":"大家好,测试兼职",		 
                        "digest":"digest",
                        "show_cover_pic":1,
                        "need_open_comment":1,
                        "only_fans_can_comment":1
                    }
               ]
            })

            //{"status":0,"message":"成功","data":{"type":"news","media_id":"3prqdD8W38nDnrK2h-qnmM8rgu5-hCY5ItnghDrRL7Z7oM8ckx0JnhWIotCtYC70","created_at":1698348318,"item":[]}}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //获取临时素材
    @Get('media_get')
    async mediaGet() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/media/get', {
                media_id: '3prqdD8W38nDnrK2h-qnmM8rgu5-hCY5ItnghDrRL7Z7oM8ckx0JnhWIotCtYC70'
            })

            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //获取永久素材
    @Get('get_material')
    async getMaterial() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/material/get_material', {
                media_id: '3prqdD8W38nDnrK2h-qnmM8rgu5-hCY5ItnghDrRL7Z7oM8ckx0JnhWIotCtYC70'
            })

            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //获取永久素材列表
    @Get('get_materials')
    async getMaterials() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/material/batchget_material', {
                type: 'image',
                offset : 0,
                count: 10
            })

            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //获取永久素材数量
    @Get('material_count')
    async materialCount() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/material/get_materialcount', {})

            //{"voice_count":0,"video_count":0,"image_count":0,"news_count":0}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    @Get('post_message')
    async postMessage(){
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/message/template/send',{
                "touser":"o4VHC6s1L_CNBfOsmHLJGJLQmBvw",
                "template_id":"u6oD79ficE6XlzDKCVaR_SVs7-GdCkyknXZt-oX3gYQ",
                //"url":"http://weixin.qq.com/download",  
                // "miniprogram":{
                //   "appid":"xiaochengxuappid12345",
                //   "pagepath":"index?foo=bar"
                // },
                "client_msg_id":"MSG_000002",
                "data":{
        
                        "task_title":{
                            "value":"黄埔御景湾酒店帮工"
                        },
                        "task_job_name": {
                            "value":"西餐厅服务员"
                        },
                        "wx": {
                            "value":"beckham996"
                        }
                }
            })

            return JsonApiResponse.object(res)
        } catch (error) {
            return JsonApiResponse.object(error)
        }
    }
    
    //获取永久带参数二维码
    @Get('office_qrcode')
    async officeQrcode() {
        try {
            const res = await this.weixinService.officeQrcode({
                "action_name": "QR_LIMIT_SCENE", 
                "action_info": {
                    "scene": {
                        "scene_id": 1
                    }
                }
            })

            // const res = await this.weixinService
            // .officialAccount
            // .getClient()
            // .httpPostJson('https://api.weixin.qq.com/cgi-bin/qrcode/create', 
            // })

            //{"ticket":"gQGX7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjJiUHR4eGhmMkcxMDAwMHcwM3YAAgRMZDtlAwQAAAAA","url":"http://weixin.qq.com/q/02r2bPtxxhf2G10000w03v"}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //日期-图文阅读当日累计:  getarticlesummary
    //某天所有被阅读过的文章（仅包括群发的文章）在当天的阅读次数等数据
    @Get('day_count')
    async dayCount() {
        try {
            const date = dayjs().add(-2,'day').format('YYYY-MM-DD')
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/datacube/getarticlesummary',{ 
                "begin_date": date, 
                "end_date": date
            })

            //{"ticket":"gQGX7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjJiUHR4eGhmMkcxMDAwMHcwM3YAAgRMZDtlAwQAAAAA","url":"http://weixin.qq.com/q/02r2bPtxxhf2G10000w03v"}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }
    
    //日期-图文阅读当日累计:  getarticlesummary
    //某天群发的文章-从群发日起持续至今累计:
    @Get('all_count')
    async allCount() {
        try {
            const date = dayjs().add(-6,'day').format('YYYY-MM-DD')
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/datacube/getarticletotal',{ 
                "begin_date": date, 
                "end_date": date
            })

            //{"ticket":"gQGX7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjJiUHR4eGhmMkcxMDAwMHcwM3YAAgRMZDtlAwQAAAAA","url":"http://weixin.qq.com/q/02r2bPtxxhf2G10000w03v"}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    //获取永久带参数二维码
    @Get('ticket2qrcode')
    async ticket2Qrcode() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .request({
                url:'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQGX7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjJiUHR4eGhmMkcxMDAwMHcwM3YAAgRMZDtlAwQAAAAA',
                method: 'GET',
                responseType: 'arraybuffer' //响应类型决定res.data 返回的数据类型 string | arraybuffer | uint8array
            })

            //{"ticket":"gQGX7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAycjJiUHR4eGhmMkcxMDAwMHcwM3YAAgRMZDtlAwQAAAAA","url":"http://weixin.qq.com/q/02r2bPtxxhf2G10000w03v"}
            return JsonApiResponse.OK()
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }

    @Get('get_published')
    async get_published(@Res() response : Response) {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/freepublish/batchget',{ 
                "offset":0,
                "count":1,
                "no_content": 0
            })

            const content : string = res.item[0].content.news_item[0].content
            // const html = `<html>
            // <meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1″>
            // <body>
            //     ${content}
            // </body>
            // </html>
            // ` 
            
            response.send(content.replaceAll('https://mmbiz.qpic.cn','http://www.apesk.net/mmbiz'))
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }
    
    @Get('get_published_list')
    async get_published_list() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/freepublish/batchget',{ 
                "offset":0,
                "count":20,
                "no_content": 1 //1.不要内容
            })

            let content = JSON.stringify(res)
            content = content.replaceAll('https://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')
            content = content.replaceAll('http://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')
            content = content.replaceAll('https://mmbiz.qlogo.cn','http://www.apesk.net/mmbiz')
            
            return JsonApiResponse.object(JSON.parse(content))
        } catch (error) {
            console.log(error)
            return JsonApiResponse.ERR(error)
        }
    }

    //获取永久素材数量
    @Get('news_count')
    async newsCount() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/material/get_materialcount', {
                type:'news'
            })

            //{"voice_count":0,"video_count":0,"image_count":0,"news_count":0}
            return JsonApiResponse.object(res)
        } catch (error) {
            console.log(error)
            return JsonApiResponse.object(error)
        }
    }


    //获取永久素材列表
    @Get('get_news')
    async getNews() {
        try {
            const res = await this.weixinService
            .officialAccount
            .getClient()
            .httpPostJson('https://api.weixin.qq.com/cgi-bin/material/batchget_material', {
                type: 'news',
                offset : 0,
                count: 3
            })

            let content = JSON.stringify(res)
            content = content.replaceAll('https://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')
            content = content.replaceAll('http://mmbiz.qpic.cn','http://www.apesk.net/mmbiz')

            // const html = `<html>
            // <meta name=”viewport” content=”width=device-width, initial-scale=1, maximum-scale=1″>
            // <body>
            //     ${content}
            // </body>
            // </html>
            // ` 
            
            //response.send(content)

            return JsonApiResponse.object(JSON.parse(content))
        } catch (error) {
            console.log(error)
            return JsonApiResponse.ERR(error)
        }
    }
    
    @Get('clear_quota')
    async clearQuota() {
        try {
            await this.weixinService.clearQuota()
            return JsonApiResponse.OK()
        } catch (error) {
            console.log(error)
            return JsonApiResponse.ERR(error)
        }
    }

    @Post('render')
    render(@Body() body,@Res() response : Response)
    {
        const htmlContent = response.render('template',body)
 
        
        return JsonApiResponse.string(htmlContent)
    }

    @Post('html')
    async html(@Body() body){
        const knex = knext(this)

        let result = await knex.fromORM(OfficePosts).insert({title:'新建文章',html:body.html})
 
        return 'HI'
    }

    @Get('html')
    async htmlGet(@Query() query){
        const knex = knext(this)

        let result = await knex.fromORM(OfficePosts).where({id:query.id}).getOne()
 
        return JsonApiResponse.object(result)
    }

    @Post('create_post')
    async createPost(@Body() body)
    {
        const knex = knext(this)
  
        let result = await knex.fromORM(OfficePosts).insert({
            title:body.title,
            digest:body.digest,
            html:body.html,
            thumb_url:body.thumb_url,
            created_at:dayjs().format('YYYY-MM-DD')
        }).then()
 
        return 'HI'

        return JsonApiResponse.OK()
    }

    @Post('delete_post')
    async deletePost(@Body() body)
    {
        const knex = knext(this)
  
        if(await knex.fromORM(OfficePosts) 
            .where({id:body.id})
            .softDelete() > 0)
           
        {
            return JsonApiResponse.OK()
        }
        else{
            return JsonApiResponse.ERR('无法删除')
        }
    }

    @Get('posts')
    async posts(@Query() query) {
        const knex = knext(this)

        let result = await knex.fromORM(OfficePosts).populate()

        const posts = result

        return JsonApiResponse.object(posts)
    }

    @Get('post')
    async post(@Query() query) {
        const knex = knext(this)

        let result = await knex.fromORM(OfficePosts)
            .where({id:query.id})
            .getOne()

        const post = result

        return JsonApiResponse.object(post)
    }

    //用选择发送 news-list-to-send
    @Get('news')
    async news(@Query() query) {
        const knex = knext(this)

        let w = [dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')]

        const res = await knex.fromORM(OfficeNews)
        .select([
            ...knex.fieldsAll(OfficeNews),
            //此消息该账号发送成功总次数
            knex.fromORM(OfficeNewsSendRecords)
            .select(knex.raw('COUNT(created_at)'))
            .where({news_id:knex.ref('office_news.id')})
            .where('office_id','=',query.office_id)
            .whereNotNull('msg_ok')
            .where('msg_ok','>',0)
            .as('send_count'),
            //今日发布成功次数
            knex.fromORM(OfficeNewsSendRecords)
            .select(knex.raw('COUNT(created_at)'))
            .where({news_id:knex.ref('office_news.id')})
            .where('office_id','=',query.office_id)
            .whereNotNull('msg_ok')
            .where('msg_ok','>',0)
            .whereBetween('created_at',[dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'),dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss')])
            .as('daily_count')
        ])
        .withEntity(OfficePosts,'postsPivots',(qb)=>{
            qb.selectExcludes<OfficePosts>(OfficePosts,['html'])
        },'posts')
        .filter((news)=>{
            return news.posts.length > 0
        })
        .orderBy('created_at','desc')
        .populate()
 
        return JsonApiResponse.object(res)
    }

    //消息列表
    @Get('template_news_list')
    async templateNewsList(@Req()request,@Query() query) {
        const knex = knext(this)

        // try {
            const res = await knex.fromORM(OfficeNews)
            .select([
                ...knex.fieldsAll(OfficeNews),
                knex.fromORM(OfficeNewsSendRecords)
                .select(knex.raw('COUNT(created_at)'))
                .where({news_id:knex.ref('office_news.id')})
                .where('office_id','=',query.office_id)
                .whereNotNull('msg_ok')
                .where('msg_ok','>',0)
                .as('send_count')
            ])
            .withEntity(OfficePosts,'postsPivots',(qb)=>{
                qb.selectExcludes<OfficePosts>(OfficePosts,['html'])
            },'posts','asc')
            .filter((news)=>{
                return news.posts.length > 0
            })
            .orderBy('created_at','desc')
            .populate()

            return JsonApiResponse.object(res)
        // } catch (error) {
        //     throw new InternalServerErrorException(error)
        // } 
    }

    // 群发消息
    @Get('send_news')
    async send_news(@Query() body){
        const knex = knext(this)
        const office_id = body.office_id
        const news_id = body.news_id

        if(!office_id || !news_id)
        {
            return JsonApiResponse.ERR('参数不正确')
        }

        if(await knex.fromORM(OfficeNewsSendRecords)
        .where({
            news_id,
            office_id,
        })
        .whereNull('msg_ok')
        .getOne())
        {
            return JsonApiResponse.ERR('正在群发,还未完成.')
        }
        
        let recordResult = await knex.fromORM(OfficeNewsSendRecords)
        .insert({
            news_id,
            office_id,
            created_at:  dayjs().format('YYYY-MM-DDTHH:mm:ss'),
        })

        await this.weixinService.send_news({
            office_id,
            news_id,
            record_id:recordResult[0]
        })

        return JsonApiResponse.OK()
    }

    @Get('news_status')
    async newsStatus()
    {
        let res = await this.weixinService.newsStatus(1000000005)
        return JsonApiResponse.object(res)
    }

    // 群发历史记录
    @Get('news_history')
    async newsHistory(@Query() body){
        const knex = knext(this)
        const office_id = body.office_id

        let result = await knex
        .fromORM(OfficeNewsSendRecords)
        .select(
            knex.fieldsExcludes<OfficeNewsSendRecords>
            (OfficeNewsSendRecords,['exception','mediaId'])
        )
        .where({
            office_id:office_id
        })
        .withEntity(OfficeNews,'news',(qb)=>{
            qb.withEntity(OfficePosts,'postsPivots',qb=>{
                qb.selectExcludes<OfficePosts>(OfficePosts,['html','url','contentSourceUrl'])
            },'posts')
        })
        .filter(record=>{
            return record.news.posts.length > 0
        })
        .orderBy('created_at','desc')
        .populate()

        return JsonApiResponse.object(result)
    }

    @Post('create_news')
    async create_news(@Body('post_ids') post_ids) { //@Body() body
        const knex = knext(this)

        post_ids = post_ids.split(',')

        let now = dayjs().format('YYYY-MM-DD HH:mm:ss')

        let ids = await knex.fromORM(OfficeNews).insert({
            updated_at:now,
            created_at:now
        })


        let news_id = ids[0]
        let items = post_ids.map((post_id)=>{
            return {
                news_id:news_id,
                post_id:post_id,
            }
        })

        let refs = await knex.fromORM(OfficeNewsPostsPivots).insert(items)

        return JsonApiResponse.OK()
    }

    @Post('delete_news')
    async deleteNews(@Body() body){
        const knex = knext(this)

        let results = await knex.fromORM(OfficeNews)
        .softDelete()
        .where({id:body.news_id})

        // let refs = await knex.fromORM(OfficeNewsPostsPivots)
        // .delete()
        // .where({news_id:body.news_id})

        return JsonApiResponse.OK()
    }
    

    @Post('create_account')
    async create_account(@Body() body) {
        const knex = knext(this)
        let res = await knex
        .fromORM(OfficeAccounts)
        .findOrCreate(
            knex.fieldsAll<OfficeAccounts>(OfficeAccounts),
            {app_id:body.app_id},
            body
        )

        return JsonApiResponse.object(res)
    }

    @Get('accounts')
    async accounts(){
        const knex = knext(this)

        const results = await knex.fromORM(OfficeAccounts)
        .select([
            ...knex.fieldsAll(OfficeAccounts),
            //最近发布时间
            knex.fromORM(OfficeNewsSendRecords)
            .select(knex.raw('MAX(created_at)'))
            .where({office_id:knex.ref('office_accounts.id')})
            .whereNotNull('msg_ok')
            .where('msg_ok','>',0)
            .as('last_datetime'),
            //今日发布成功次数
            knex.fromORM(OfficeNewsSendRecords)
            .select(knex.raw('COUNT(created_at)'))
            .where({office_id:knex.ref('office_accounts.id')})
            .whereNotNull('msg_ok')
            .where('msg_ok','>',0)
            .where('created_at','>',dayjs().format('YYYY-MM-DD'))
            .as('send_count')
        ])

        return JsonApiResponse.object(results)
    }

    @Get('account')
    async account(@Query('office_id') office_id){
        const knex = knext(this)

        const result = await knex.fromORM(OfficeAccounts).where({id:office_id}).getOne()

        return JsonApiResponse.object(result)
    }

    @Post('account_modify')
    async accountModify(@Body() body){
        const knex = knext(this)

        let params = _.pick(body,...knex.fieldsExcludes<OfficeAccounts>(OfficeAccounts,['id']))
        const result = await knex.fromORM(OfficeAccounts)
        .update(params)
        .where({id:body.office_id})

        return JsonApiResponse.object(result)
    }
}
